package com.seagull.sb.security;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.ext.Provider;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.seagull.sb.dao.AuthenticationDAO;
import com.seagull.sb.domain.Student;
import com.seagull.sb.domain.Teacher;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerRequestFilter;
import com.sun.jersey.spi.container.ContainerResponseFilter;
import com.sun.jersey.spi.container.ResourceFilter;
 
/**
 * Filter all incoming requests, look for possible session information and use that
 * to create and load a SecurityContext to request. 
 * @author rameshkale@seagull.com
 * 
 */
@Component   // let spring manage the lifecycle
@Provider    // register as jersey's provider
public class SecurityContextFilter implements ResourceFilter, ContainerRequestFilter {
 
//    @Autowired
//    private SessionRepository sessionRepository;  // DAO to access Session
//    @Autowired
//    private UserRepository userRepository;  // DAO to access User

	@Autowired
	private AuthenticationDAO authenticationDAO;
	
	@Context
	SecurityContext sc;
     
    @Override
    public ContainerRequest filter(ContainerRequest request) {

        BaseUser user = null;
        Student student;
        Teacher teacher;
        
        String auth = request.getHeaderValue("authorization");
        String role = request.getHeaderValue("role");
        
        String[] lap = BasicAuth.decode(auth);
        if(auth == null)
            throw new WebApplicationException(Status.UNAUTHORIZED);
        if(role == null || "".equals(role.trim()))
            throw new WebApplicationException(Status.UNAUTHORIZED);
        if(lap == null || lap.length != 2) 
            throw new WebApplicationException(Status.UNAUTHORIZED);
        
        
        if(BaseUser.Role.teacher.toString().equals(role)){
        	try {
				teacher = authenticationDAO.findTeacher(new StringBuffer(lap[0]), lap[1]);
				if(teacher==null)
					throw new Exception("Teacher authentication failed.");
				user = new UserTeacher(teacher);
				
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        }else if (BaseUser.Role.student.toString().equalsIgnoreCase(role)){
            try {
    			student = authenticationDAO.findStudent(lap[0], lap[1]);
    			if(student==null)
    				throw new Exception("Student authentication failed.");
    		} catch (Exception e) {
    			throw new WebApplicationException(Status.UNAUTHORIZED);
    		}
            user = new UserStudent(student);
        }else{
        	throw new WebApplicationException(Status.FORBIDDEN);// return for bidden when there is no role in header.
        }
        request.setSecurityContext(new SBSecurityContext(user));

        return request;
    }
 
    @Override
    public ContainerRequestFilter getRequestFilter() {
        return this;
    }
 
    @Override
    public ContainerResponseFilter getResponseFilter() {
        return null;
    }

	public AuthenticationDAO getAuthenticationDAO() {
		return authenticationDAO;
	}

	public void setAuthenticationDAO(AuthenticationDAO authenticationDAO) {
		this.authenticationDAO = authenticationDAO;
	}
}